<template>
  <div style="overflow-y: hidden; background: #fff">
    <div class="op-btns">
      <px-form ref="queryRef" class="custom-form-ui" :model="queryParams" inline label-width="90px">
        <px-form-item label="时间" prop="timeRange" style="width: 420px">
          <px-date-picker
            v-model="queryParams.timeRange"
            :type="props.isDate ? 'daterange' : 'datetimerange'"
            range-separator="至"
            start-placeholder="请选择开始时间"
            end-placeholder="请选择结束时间"
            :format="props.isDate ? 'YYYY-MM-DD' : 'YYYY-MM-DD HH:mm:ss'"
            :value-format="props.isDate ? 'YYYY-MM-DD' : 'YYYY-MM-DD HH:mm:ss'"
          />
        </px-form-item>

        <px-form-item class="option-item">
          <px-button type="primary" @click="searchAction">查询</px-button>
          <px-button type="primary" plain @click="exportAction">导出</px-button>
        </px-form-item>
      </px-form>
    </div>
    <div class="table-content" :height="pageFrom == 'vocReport' ? 'calc(100vh - 340px)' : 'calc(100vh - 220px)'">
      <div v-if="operation == 'edit'" class="equip-table-btn" style="margin-bottom: 10px">
        <px-button type="primary" :disabled="!headerList.length" @click="handleAdd">新增</px-button>
      </div>
      <px-table
        :data="tableData"
        class="equip-table"
        :height="pageFrom == 'vocReport' ? 'calc(100vh - 400px)' : 'calc(100vh - 280px)'"
        border
        :span-method="objectSpanMethod"
      >
        <template #empty>
          <px-empty />
        </template>
        <px-table-column v-if="showYearMonth" prop="yearMonth" label="年月" min-width="120" />
        <px-table-column prop="ctime" label="时间" min-width="100">
          <template #default="scope">
            <div>{{ props.isDate ? dayjs(scope.row.ctime).format("YYYY-MM-DD") : dayjs(scope.row.ctime).format("YYYY-MM-DD HH:mm:ss") }}</div>
          </template>
        </px-table-column>
        <template v-for="(item, index) in headerList" :key="index">
          <px-table-column v-if="item.parentColumn" :prop="item.parentColumn" :label="item.parentColumn" min-width="120" align="center">
            <px-table-column
              v-for="(citem, index) in item.itemList"
              :key="index"
              :label="citem.itemName"
              :min-width="citem.columnWidth || 120"
              align="center"
            >
              <px-table-column v-if="citem.columnDesc" :label="citem.columnDesc" :min-width="citem.columnWidth || 120" align="center">
                <template #default="scope">
                  <div>{{ scope.row[citem.itemCode]?.meterReadingVal }}</div>
                </template>
              </px-table-column>
              <template v-if="!item.columnDesc" #default="scope">
                <div>{{ scope.row[citem.itemCode]?.meterReadingVal }}</div>
              </template>
            </px-table-column>
          </px-table-column>
          <px-table-column v-if="!item.parentColumn" :prop="item.itemCode" :label="item.itemName" :min-width="item.columnWidth || 120">
            <px-table-column v-if="item.columnDesc" :label="item.columnDesc" :min-width="item.columnWidth || 120">
              <template #default="scope">
                <div>{{ scope.row[item.itemCode]?.meterReadingVal }}</div>
              </template>
            </px-table-column>
            <template v-if="!item.columnDesc" #default="scope">
              <div>{{ scope.row[item.itemCode]?.meterReadingVal }}</div>
            </template>
          </px-table-column>
        </template>
        <px-table-column v-if="showDailyTotal" prop="dailyTotal" label="日总量" min-width="120" fixed="right" align="center" />
        <px-table-column v-if="showMonthlyTotal" prop="dailyAverage" label="日均值" min-width="120" fixed="right" align="center">
          <template #default="scope">
            <div>{{ calculateMonthlyTotal(scope.row).av }}</div>
          </template>
        </px-table-column>
        <px-table-column v-if="showMonthlyTotal" prop="monthlyTotal" label="月总量" min-width="120" fixed="right" align="center">
          <template #default="scope">
            <div>{{ calculateMonthlyTotal(scope.row).total }}</div>
          </template>
        </px-table-column>
        <px-table-column v-if="operation == 'edit'" prop="operation" label="操作" width="120" fixed="right" align="center">
          <template #default="scope">
            <px-tooltip content="编辑" placement="top">
              <px-button link icon="EditPen" type="primary" @click="handleEdit(scope.row)" />
            </px-tooltip>
            <px-tooltip content="删除" placement="top">
              <px-button link icon="Delete" type="danger" @click="handleDelete(scope.row)" />
            </px-tooltip>
          </template>
        </px-table-column>
      </px-table>
    </div>
    <px-dialog v-model="dialogVisible" :title="dialogType == 'add' ? '新增' : '编辑'" width="680" @close="closeDialog">
      <px-form ref="formRef" :model="editFormParams" label-width="210px" label-position="right" :rules="editRules">
        <px-form-item label="时间" prop="ctime">
          <px-date-picker
            v-model="editFormParams.ctime"
            :type="props.isDate ? 'date' : 'datetime'"
            placeholder="请选择"
            style="width: 100%"
            :format="props.isDate ? 'YYYY-MM-DD' : 'YYYY-MM-DD HH:mm:ss'"
            :value-format="props.isDate ? 'YYYY-MM-DD' : 'YYYY-MM-DD HH:mm:ss'"
          />
        </px-form-item>
        <px-form-item v-for="(item, index) in formItemList" :key="index" :label="item.itemName" :prop="item.itemCode">
          <px-input-number v-if="item.inputType == 'number'" v-model="editFormParams[`${item.itemCode}`]" placeholder="请输入" maxlength="60" />
          <px-input v-else v-model="editFormParams[`${item.itemCode}`]" type="text" placeholder="请输入" maxlength="60" />
        </px-form-item>
      </px-form>
      <template #footer>
        <span class="dialog-footer">
          <px-button @click="closeDialog">取消</px-button>
          <px-button v-optimize:debounce="{ event: 'click', fn: () => confirmAction(), timeout: 500 }" type="primary"> 确定 </px-button>
        </span>
      </template>
    </px-dialog>
  </div>
</template>

<script setup lang="ts">
import { onMounted, reactive, toRefs, ref, computed, nextTick, toRaw, watch } from "vue";
import { PxMessage, PxMessageBox } from "px-ui";
import { useRouter, useRoute } from "vue-router";
import { useNav } from "@/layout/hooks/useNav";
import dayjs from "dayjs";
import { queryMeterReadingItems, queryMeterDataList, removeBySequence, saveBySequence } from "@/api/manualMeter";
import { getToken } from "@/utils/auth";

defineOptions({
  name: "MANUAL_METER"
});
interface Props {
  groupCode: string;
  showYearMonth?: boolean;
  showDailyTotal?: boolean;
  showDailyAverage?: boolean;
  showMonthlyTotal?: boolean;
  operation?: string;
  exportFileName: string;
  pageFrom?: string;
  isDate?: boolean;
}

const props = withDefaults(defineProps<Props>(), {
  showYearMonth: false,
  showDailyTotal: false,
  showDailyAverage: false,
  showMonthlyTotal: false,
  operation: "edit"
});

const { username } = useNav();
const router = useRouter();
const route = useRoute();

const dialogVisible = ref(false);
const dialogType = ref("add"); // 弹窗默认新增
const editFormParams = ref({});
const formRef = ref(null);
const tableData = ref([]);
const headerList = ref([]);
const usageCodes = ref([]);
const formItemList = ref([]);

const templateUrl = ref();

const queryParams = reactive({
  timeRange: "",
  groupCode: props.groupCode
});
function numberAdd(a, b) {
  const factor = 10 ** 10; // 根据需要调整因子
  return (Math.round(a * factor) + Math.round(b * factor)) / factor;
}
const calculateMonthlyTotal = row => {
  // 提取年月
  const yearMonth = row.yearMonth;
  let total = 0;
  let av = 0;
  let rows = 0;
  total = tableData.value.reduce((total, item) => {
    if (item.yearMonth == yearMonth) {
      rows++;
      return numberAdd(total, item.dailyTotal);
    }
    return total;
  }, 0);
  if (rows == 0) {
    av = total;
  } else {
    av = (total / rows).toFixed(2);
  }
  return {
    total,
    av
  };
};
const objectSpanMethod = ({ row, column, rowIndex, columnIndex }) => {
  if (column.property == "monthlyTotal" || column.property == "yearMonth" || column.property == "dailyAverage") {
    const yearMonth = row.yearMonth;
    let count = 0;
    tableData.value.forEach(item => {
      if (item.yearMonth == yearMonth) {
        count++;
      }
    });
    let firstIndex = tableData.value.findIndex(v => v.yearMonth == yearMonth);
    if (rowIndex == firstIndex) {
      return {
        rowspan: count,
        colspan: 1
      };
    } else {
      return {
        rowspan: 0,
        colspan: 0
      };
    }
  }
};
const { VITE_FANRUAN_BASE_URL } = import.meta.env;
const exportAction = () => {
  if (!queryParams.groupCode) {
    PxMessage({
      message: "抄表组不能为空",
      type: "error"
    });
    return;
  }
  if (queryParams?.timeRange != null && queryParams?.timeRange.length > 0) {
    let token = getToken().accessToken || "";
    let hostname = window.location.hostname;
    let protocol = window.location.protocol;
    let url = `${VITE_FANRUAN_BASE_URL}/webroot/decision/view/report?viewlet=manualMeter%252F%25E6%2589%258B%25E6%258A%2584%25E8%25A1%25A8%25E5%25AF%25BC%25E5%2587%25BA.cpt&format=excel&extype=simple&token=${token}&startTime=${queryParams.timeRange?.[0]}&endTime=${queryParams.timeRange?.[1]}&apiHost=${protocol}//${hostname}&groupCode=${queryParams.groupCode}&showYearMonth=${props.showYearMonth}&showDailyTotal=${props.showDailyTotal}&showDailyAverage=${props.showDailyAverage}&showMonthlyTotal=${props.showMonthlyTotal}&isDate=${props.isDate}&__filename__=${props.exportFileName}&facCode=${localStorage.getItem("facCode") || ""}`;
    window.location.href = url;
  } else {
    PxMessage({
      message: "请选择时间后再导出",
      type: "error"
    });
  }
};

const editRules = computed(() => {
  let obj = {
    ctime: [{ required: true, message: "请选择", trigger: "change" }]
  };
  formItemList.value.forEach(v => {
    obj[`${v.itemCode}`] = [{ required: true, message: "请输入", trigger: "blur" }];
  });
  return obj;
});
const handleAdd = () => {
  dialogType.value = "add";
  dialogVisible.value = true;
  formRef.value?.clearValidate();
  editFormParams.value = {
    ctime: "",
    sequence: ""
  };
};
const handleEdit = row => {
  dialogType.value = "edit";
  editFormParams.value.ctime = row.ctime;
  editFormParams.value.sequence = row.sequence;
  formItemList.value.forEach(v => {
    editFormParams.value[v.itemCode] = row[v.itemCode].meterReadingVal;
    v.meterReadingVal = row[v.itemCode].meterReadingVal;
    v.id = row[v.itemCode].id;
    v.sequence = row[v.itemCode].sequence;
  });
  dialogVisible.value = true;
  formRef.value?.clearValidate();
};
const handleDelete = row => {
  PxMessageBox.confirm(`是否删除该条记录数据？`, "温馨提示", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
    draggable: true
  })
    .then(async () => {
      await removeBySequence([row.sequence]);
      PxMessage.success("删除成功");
      getTableData();
    })
    .catch(() => {});
};
const confirmAction = () => {
  formRef.value?.validate(async (valid, fields) => {
    if (valid) {
      let meterReadingData = [];
      let params = {
        groupCode: queryParams.groupCode,
        sequence: dialogType.value == "edit" ? editFormParams.value.sequence : undefined,
        ctime: dayjs(editFormParams.value.ctime).format("YYYY-MM-DD HH:mm:ss"),
        meterReadingData: []
      };
      formItemList.value.forEach(v => {
        meterReadingData.push({
          sequence: dialogType.value == "edit" ? v.sequence : undefined,
          ctime: dayjs(editFormParams.value.ctime).format("YYYY-MM-DD HH:mm:ss"),
          valTime: dayjs(editFormParams.value.ctime).format("YYYY-MM-DD HH:mm:ss"),
          id: v.id,
          itemCode: v.itemCode,
          meterReadingVal: editFormParams.value[v.itemCode]
        });
      });
      params.meterReadingData = meterReadingData;
      let res = await saveBySequence({ ...params });
      PxMessage.success(dialogType.value == "edit" ? "更新成功" : "保存成功");
      closeDialog();
      getTableData();
    } else {
      console.log("error submit!", fields);
    }
  });
};
// 关闭弹窗
const closeDialog = () => {
  formRef.value?.clearValidate();
  dialogVisible.value = false;
};
const getHeaderList = async () => {
  usageCodes.value = [];
  let tCodes = [];
  if (!queryParams.groupCode) {
    headerList.value = [];
    formItemList.value = [];
    tableData.value = [];
    return;
  }
  let res: any = await queryMeterReadingItems({ groupCode: queryParams.groupCode });
  headerList.value = res;
  headerList.value.forEach(v => {
    v.columnDesc = "";
    if (v.extJson) {
      let j = JSON.parse(v.extJson);
      v.columnDesc = j?.column?.desc;
      v.parentColumn = j?.column?.parent;
      v.isUsage = j?.column?.isUsage;
      v.columnWidth = j?.column?.width;
      if (j?.column?.isUsage) {
        tCodes.push(v.itemCode);
      }
    }
  });
  let tmpHeaderList = [];
  headerList.value.forEach(v => {
    if (v.parentColumn) {
      let targetIndex = tmpHeaderList.findIndex(t => t.parentColumn == v.parentColumn);
      if (targetIndex != -1) {
        tmpHeaderList[targetIndex].itemList.push(v);
      } else {
        tmpHeaderList.push({
          parentColumn: v.parentColumn,
          itemList: [toRaw(v)]
        });
      }
    } else {
      tmpHeaderList.push(v);
    }
  });
  headerList.value = tmpHeaderList;
  // labelName,meterReadingVal,itemCode,id,sequence
  formItemList.value = res.map(v => {
    let inputType = "";
    if (v.extJson) {
      let j = JSON.parse(v.extJson);
      inputType = j?.column?.inputType || "text";
    }
    return { itemName: (v.parentColumn || "") + v.itemName, itemCode: v.itemCode, meterReadingVal: "", id: "", sequence: "", inputType };
  });
  tableData.value = [];
  usageCodes.value = tCodes;
  getTableData();
};

const getTableData = async () => {
  if (!queryParams.groupCode) {
    tableData.value = [];
    return;
  }
  let res: any = await queryMeterDataList({
    groupCode: queryParams.groupCode,
    startTime: queryParams.timeRange?.[0],
    endTime: queryParams.timeRange?.[1]
  });
  // 组装数据 年月、日总、日均，月总
  tableData.value = res;
  tableData.value.forEach(v => {
    let yearMonth = dayjs(v.ctime).format("YYYY-MM");
    let dailyTotal = 0;
    usageCodes.value.forEach(u => {
      dailyTotal = numberAdd(dailyTotal, v[u].meterReadingVal);
    });
    // v.dailyAverage = (dailyTotal / usageCodes.value.length).toFixed(2);
    v.dailyTotal = dailyTotal;
    v.yearMonth = yearMonth;
  });
};
onMounted(() => {
  let ym = new Date();
  if (route.query.date) {
    ym = new Date(route.query.date);
  }
  // 获取当前月份第一天
  const firstDayOfMonth = dayjs(new Date(ym.getFullYear(), ym.getMonth(), 1)).format("YYYY-MM-DD HH:mm:ss");
  // 获取当前月份最后一天
  const lastDayOfMonth = dayjs(new Date(ym.getFullYear(), ym.getMonth() + 1, 0)).format("YYYY-MM-DD HH:mm:ss");
  queryParams.timeRange = [firstDayOfMonth, lastDayOfMonth];
  // getUrl();
  getHeaderList();
  // getTableData();
});
watch(
  () => props.groupCode,
  newValue => {
    console.log("watch groupCode", props.groupCode);
    console.log("watch groupCode newValue", newValue);
    queryParams.groupCode = newValue;
    getHeaderList();
  },
  {
    immediate: true,
    deep: true
  }
);

const searchAction = () => {
  getTableData();
};
</script>
<style scoped lang="scss">
@import url("@/views/all/equip/scss/table-list.scss");

.template-content {
  width: 100%;
  background-color: #fff;
}

.custom-form-ui {
  height: 38px;

  .px-form-item {
    margin-bottom: 0;
  }
}

.op-btns {
  display: flex;
  padding: 16px;
  // margin: 5px 0;
  background-color: #fff;
  // box-shadow: 0 0 10px 0 rgb(0 0 0 / 10%);

  .left {
    flex: 1;
    text-align: left;
  }

  .center {
    flex: 1;
    text-align: center;
  }

  .right {
    flex: 1;
    text-align: right;
  }
}

.table-content {
  position: relative;
  // height: calc(100vh - 220px);
  padding: 16px;
  // margin-bottom: 16px;
  overflow-y: hidden;
  background: #fff;
}

.footer-btns {
  text-align: right;
}

:deep(.px-table) {
  .px-table__cell {
    padding: 6px 0;
  }

  .px-table__header-wrapper,
  .px-table__fixed-header-wrapper {
    th {
      background-color: #e7eefb !important;
    }
  }
}
</style>
